package pseudoAssemblerCompiler.twopassassembler.view.windows;

import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.FormAttachment;
import org.eclipse.swt.layout.FormData;
import org.eclipse.swt.layout.FormLayout;
import org.eclipse.swt.layout.RowLayout;
import org.eclipse.swt.widgets.*;
import pseudoAssemblerCompiler.twopassassembler.controller.OperationCodeController;
import pseudoAssemblerCompiler.twopassassembler.exceptions.RequiredDataNotSetException;
import pseudoAssemblerCompiler.twopassassembler.view.ui.autocomplete.AutoCompleteCombo;
import pseudoAssemblerCompiler.twopassassembler.view.ui.autocomplete.ComboDisplayFormat;
import pseudoAssemblerCompiler.twopassassembler.view.ui.autocomplete.ItemSelectionListener;
import pseudoAssemblerCompiler.twopassassembler.view.util.DialogWindowContainer;
import pseudoAssemblerCompiler.twopassassembler.view.util.LabeledContainer;

import java.util.ArrayList;
import java.util.List;

/**
 * User: Роман
 * Date: 22.03.12
 * Time: 18:18
 */
public class AddCodeOperationWindow implements Window {


    private OperationCodeController _controller;

    public static final String MNEMONIC_CODE = "МКОП";

    public static final String BINARY_CODE = "Двоичный код";

    public static final String LENGTH_OF_COMMAND = "Длина команды";

    public static final String TYPE_OF_ADDRESSING = "Тип адресации";

    public static final String DIRECTIVE = "Директива";
    private DialogWindowContainer _container;
    private LabeledContainer _labeledMnemonicCode;
    private LabeledContainer _labeledBinaryCode;
    private LabeledContainer _labeledLengthOfCode;

    private LabeledContainer _labeledDirective;
    private Text _mnemonicCode;
    private AutoCompleteCombo _binaryCode;
    private AutoCompleteCombo _lengthOfCode;
    private Button _directive;
    private Button _add;
    private Button _cancel;

    private Composite _typeOfAddressing;
    private Button _straight;
    private Button _direct;

    public AddCodeOperationWindow(Display aDisplay, String aNameOfWindow) {
        _container = new DialogWindowContainer(aDisplay, aNameOfWindow, 500, 300);

        _labeledMnemonicCode =
                new LabeledContainer(_container.get_composite(), MNEMONIC_CODE);
        _labeledBinaryCode =
                new LabeledContainer(_container.get_composite(), BINARY_CODE);
        _labeledLengthOfCode =
                new LabeledContainer(_container.get_composite(), LENGTH_OF_COMMAND);
        _labeledDirective =
                new LabeledContainer(_container.get_composite(), DIRECTIVE);

        _mnemonicCode = new Text(_labeledMnemonicCode.getControlComposite(), SWT.BORDER);

        List<Integer> binaryCodes = new ArrayList<Integer>(256);
        for (int i = 0; i < 256; i++) {
            binaryCodes.add(i);
        }

        _binaryCode = new AutoCompleteCombo(
                _labeledBinaryCode.getControlComposite(),
                SWT.BORDER, binaryCodes,
                new ComboDisplayFormat<Integer>() {
                    @Override
                    public String getDisplayName(Integer object) {
                        return object == null ? "" : Integer.toHexString(object);
                    }

                    @Override
                    public String getPrimaryKey(Integer object) {
                        return object.toString();
                    }

                    @Override
                    public String getDescription(Integer object) {
                        return null;
                    }
                });

        List<Integer> lengthOfCodes = new ArrayList<Integer>(5);
        for (int i = 0; i < 5; i++) {
            lengthOfCodes.add(i);
        }

        _lengthOfCode = new AutoCompleteCombo(
                _labeledLengthOfCode.getControlComposite(),
                SWT.BORDER, lengthOfCodes,
                new ComboDisplayFormat<Integer>() {
                    @Override
                    public String getDisplayName(Integer object) {
                        return object == null ? "" : Integer.toHexString(object);
                    }

                    @Override
                    public String getPrimaryKey(Integer object) {
                        return object.toString();
                    }

                    @Override
                    public String getDescription(Integer object) {
                        return null;
                    }
                });

        _typeOfAddressing = new Composite(_container.get_composite(), SWT.NONE);

        Group _group = new Group(_typeOfAddressing, SWT.SHADOW_IN);
        _group.setText(TYPE_OF_ADDRESSING);
        _group.setLayout(new RowLayout(SWT.VERTICAL));

        _straight = new Button(_group, SWT.RADIO);
        _straight.setText("Прямая");

        _direct = new Button(_group, SWT.RADIO);
        _direct.setText("Непосредственная");

        _directive = new Button(_labeledDirective.getControlComposite(), SWT.CHECK);

        _add = _container.createButton("Добавить");
        _cancel = _container.createButton("Отменить");
    }

    @Override
    public void create() {
        listeners();
        layouts();
        _container.open();
    }

    @Override
    public void setController(Object aController) {
        if (aController instanceof OperationCodeController) {
            _controller = (OperationCodeController) aController;
        }
    }

    public boolean setFocus(Control control) {
        return control.setFocus();
    }

    private void layouts() {
        FormData formData;

        formData = new FormData();
        formData.left = new FormAttachment(0, 0);
        formData.top = new FormAttachment(0, 0);
        formData.right = new FormAttachment(100, 0);
//        formData.bottom = new FormAttachment(100, 0);
        formData.height = 30;
        _labeledMnemonicCode.setLayoutData(formData);

        formData = new FormData();
        formData.left = new FormAttachment(0, 0);
        formData.top = new FormAttachment(_labeledMnemonicCode.getComposite(), 0);
        formData.right = new FormAttachment(100, 0);
//        formData.bottom = new FormAttachment(100, 0);
        formData.height = 30;
        _labeledBinaryCode.setLayoutData(formData);

        formData = new FormData();
        formData.left = new FormAttachment(0, 0);
        formData.top = new FormAttachment(_labeledBinaryCode.getComposite(), 0);
        formData.right = new FormAttachment(100, 0);
//        formData.bottom = new FormAttachment(100, 0);
        formData.height = 30;
        _labeledLengthOfCode.setLayoutData(formData);

        formData = new FormData();
        formData.left = new FormAttachment(0, 0);
        formData.top = new FormAttachment(_labeledLengthOfCode.getComposite(), 0);
        formData.right = new FormAttachment(100, 0);
//        formData.bottom = new FormAttachment(100, 0);
//        formData.height = 30;
        _typeOfAddressing.setLayout(new FormLayout());
        _typeOfAddressing.setLayoutData(formData);

        formData = new FormData();
        formData.left = new FormAttachment(0, 0);
        formData.top = new FormAttachment(_typeOfAddressing, 10);
        formData.right = new FormAttachment(100, 0);
//        formData.bottom = new FormAttachment(100, 0);
        formData.height = 30;
        _labeledDirective.setLayoutData(formData);


        formData = new FormData();
        formData.left = new FormAttachment(0, 0);
        formData.right = new FormAttachment(100, 0);
        _mnemonicCode.setLayoutData(formData);

        formData = new FormData();
        formData.left = new FormAttachment(0, 0);
        formData.top = new FormAttachment(0, 0);
        formData.right = new FormAttachment(100, 0);
        formData.height = 22;
        _binaryCode.setLayoutData(formData);

        formData = new FormData();
        formData.left = new FormAttachment(0, 0);
        formData.right = new FormAttachment(100, 0);
        _lengthOfCode.setLayoutData(formData);

        formData = new FormData();
        formData.left = new FormAttachment(0, 0);
        formData.right = new FormAttachment(100, 0);
        _directive.setLayoutData(formData);

        formData = new FormData();
        formData.top = new FormAttachment(0, 10);
        formData.right = new FormAttachment(_cancel, -10);
        formData.height = 30;
        formData.width = 100;
        _add.setLayoutData(formData);

        formData = new FormData();
        formData.top = new FormAttachment(0, 10);
        formData.right = new FormAttachment(100, -20);
        formData.height = 30;
        formData.width = 100;
        _cancel.setLayoutData(formData);
    }

    private void listeners() {
        _cancel.addSelectionListener(new SelectionAdapter() {
            @Override
            public void widgetSelected(SelectionEvent e) {
                _container.dispose();
            }
        });

        _add.addSelectionListener(new SelectionAdapter() {
            @Override
            public void widgetSelected(SelectionEvent e) {
                try {
                    addButtonTriggered();
                    _container.get_shell().dispose();
                } catch (RequiredDataNotSetException ex) {
                    _container.makeMessage(ex.getMessage());
                    if (null != ex.getControl()) {
                        setFocus(ex.getControl());
                    }
                }
            }
        });

        _binaryCode.addSelectionListener(new ItemSelectionListener() {
            @Override
            public void itemSelected(Object selectedItem) {
                Integer integer = (Integer) selectedItem;
                //
            }
        });
    }

    private void addButtonTriggered() throws RequiredDataNotSetException {
        //
    }

}
